<?php
/**
 * Copyright (c) 2006-2008, Julien PORTALIER
 * http://featherphp.googlecode.com/
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 */

/**
 * Dispatches the request.
 */
class Dispatcher
{
	static function init()
	{
		# required libs
		require FEATHER.'libs'.DS.'load.php';
		Load::_include('libs', array_merge(array(/*'base',*/ 'inflector', 'error', 'http', 'time'), Core::$libs));
		Load::_include('database', 'database');
		Load::_include('models', 'object', 'active_record_exceptions', 'active_record', 'active_resource');
	}
	
	/**
	 * Dispatches the given URL to correct controller/action.
	 *
	 * 1. Analyzes URL.
	 * 2. Creates controller.
	 * 3. Launches action.
	 * 4. Renders (if not already rendered).
	 * 
	 * @param $url String
	 */
	static function dispatch($url)
	{
		$orig_url = $url;
		
		# uniforms URL
		$url = trim($url, ' /');
		
		# bootstrap (eg: URL rewrites, redirects, etc.)
		if (!function_exists('feather_bootstrap')
			and file_exists(APP.'config'.DS.'bootstrap.php'))
		{
			include APP.'config'.DS.'bootstrap.php';
			$url = feather_bootstrap($url, HTTP::$method);
		}
		
		# starts routing
		Load::libs('routes');
		
		# is plugin?
		$segments = explode('/', $url);
		if (Routes::is_plugin($segments[0]))
		{
			Routes::set_plugin(array_shift($segments));
			$url = implode('/', $segments);
		}
		
		# routes URL
		Routes::init();
		$maps = Routes::route_url($url, HTTP::$method);
		
		try
		{
			# controller > action
			$Controller = Load::controller($maps[':controller'], $orig_url, $maps[':action'], &$maps);
			$Controller->run_action();
		}
		catch(HTTPError $e)
		{
			# displays HTTP error
			$Error = Load::controller('error_handler', $url, null, $maps);
			$Error->show($e->getCode(), $e->action, $e->data);
		}
		catch(Exception $e)
		{
			if (!DEBUG)
			{
				# logs error
				$msg = $e->getCode().' '.$e->getMessage();
				error_log($msg, 3, TMP.'logs'.DS.'exceptions.log');
			}
			else
			{
				# debug mode: rethrow exception
				throw $e;
			}
		}
	}
	
	/**
	 * Runs a script.
	 * 
	 * @param $path String
	 * @param $action String[optional]
	 * @param $params Array[optional]
	 */
	static function script($path, $action='main', array $params=null)
	{
		# controller & action
		$Script = Load::script($path, $action);
		$Script->run_action($action, $params);
	}
}
?>
